package com.costaccounting.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.costaccounting.common.annotation.ItemReport;
import com.costaccounting.common.annotation.ItemReports;
import com.costaccounting.common.core.domain.AjaxResult;

import javax.naming.Name;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

public class ItemUtil<T> {

    /**
     * 注解列表
     */
    private List<Object[]> fields;
    /**
     * 实体对象
     */
    public Class<T> clazz;

    public ItemUtil(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     * 得到所有定义字段
     */
    public Map<String, List<String>> getField() {
        this.fields = getFields();
        List<ItemReport> list = new ArrayList<>();
        for (Object[] os : fields) {
            ItemReport r = (ItemReport) os[1];
            list.add(r);
        }
        Map<String, List<ItemReport>> irMap = list.stream().collect(Collectors.groupingBy(ItemReport::cName));
        Map<String, List<String>> nameList = new HashMap<>();
        for (String s : irMap.keySet()) {
            List<ItemReport> itemReports = irMap.get(s);
            List<String> names = new ArrayList<>();
            for (ItemReport itemReport : itemReports) {
                names.add(s + "," + itemReport.name() + "," + itemReport.field());
            }
            nameList.put(s, names);
        }
        return nameList;
    }

    /**
     * 获取字段注解信息
     */
    public List<Object[]> getFields() {
        List<Object[]> fields = new ArrayList<Object[]>();
        List<Field> tempFields = new ArrayList<>();
        tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
        tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
        for (Field field : tempFields) {
            // 单注解
            if (field.isAnnotationPresent(ItemReport.class)) {
                ItemReport attr = field.getAnnotation(ItemReport.class);
                if (attr != null) {
                    field.setAccessible(true);
                    fields.add(new Object[]{field, attr});
                }
            }

            // 多注解
            if (field.isAnnotationPresent(ItemReports.class)) {
                ItemReports attrs = field.getAnnotation(ItemReports.class);
                ItemReport[] itemReports = attrs.value();
                for (ItemReport attr : itemReports) {
                    if (attr != null) {
                        field.setAccessible(true);
                        fields.add(new Object[]{field, attr});
                    }
                }
            }
        }
        return fields;
    }

    public List<BigDecimal> getReportZLine(Map<String, List<T>> listMap, List<String> month, String F) throws IllegalAccessException {
        List<BigDecimal> bList = new ArrayList<>();

        List<Object[]> fields = getFields();

        for (String M : month) {
            List<T> ts = listMap.get(M);
            if (null != ts && 0 < ts.size()) {
                Object t1 = ts.get(0);
                for (Object[] os : fields) {
                    Field field = (Field) os[0];
                    ItemReport r = (ItemReport) os[1];
                    //获取字段注释
                    String fName = r.name().toString();
                    if (F.equals(fName)) {
                        Object o = field.get(t1);
                        if (o != null) {
                            bList.add(new BigDecimal(o.toString()));
                        } else {
                            bList.add(new BigDecimal("0"));
                        }
                        break;
                    }
                }
            } else {
                bList.add(new BigDecimal("0"));
            }
        }
        return bList;
    }

    public List<BigDecimal> getReportZLineTwo(Map<String, List<T>> listMap, List<String> month, String F) throws IllegalAccessException {
        List<BigDecimal> bList = new ArrayList<>();

        List<Object[]> fields = getFields();

        for (String M : month) {
            List<T> ts = listMap.get(M);
            if (null != ts && 0 < ts.size()) {
                Object t1 = ts.get(0);
                for (Object[] os : fields) {
                    Field field = (Field) os[0];
                    ItemReport r = (ItemReport) os[1];
                    //获取字段注释
                    String fName = r.name().toString();
                    if (F.equals(fName)) {
                        Object o = field.get(t1);
                        if (o != null) {
                            bList.add(new BigDecimal(o.toString()));
                        } else {
                            bList.add(new BigDecimal("0"));
                        }
                        break;
                    }
                }
            } else {
                bList.add(new BigDecimal("0"));
            }
        }
        return bList;
    }

    public List<BigDecimal> getReportLine(List<T> list, List<String> fieldList) throws Exception {
        List<Object[]> fields = getFields();
        List<BigDecimal> bList = new ArrayList<>();
        for (Object[] os : fields) {
            Field field = (Field) os[0];
            ItemReport r = (ItemReport) os[1];
            //获取字段注释
            String fName = r.name().toString();
            if (fieldList.contains(fName)) {
                //多月
                if (list.size() > 1) {
                    BigDecimal n = new BigDecimal("0");
                    for (T t : list) {
                        Object o = field.get(t);
                        if (o != null) {
                            n = n.add(new BigDecimal(o.toString()));
                        } else {
                            n = n.add(new BigDecimal("0"));
                        }
                    }
                    bList.add(n);
                } else {
                    Object o = field.get(list.get(0));
                    if (o != null) {
                        bList.add(new BigDecimal(o.toString()));
                    } else {
                        bList.add(new BigDecimal("0"));
                    }
                }
            }
        }
//
        return bList;
    }

    /**
     * 获取bean中的属性值
     *
     * @param vo    实体对象
     * @param field 字段
     * @return 最终的属性值
     * @throws Exception
     */
    private Object getTargetValue(List<T> list, Field field) throws Exception {

        for (T vo : list) {
            Object o = field.get(vo);
        }
        return new Object();
    }

}
